// 定义一个依赖容器，用于存储和检索依赖项
class DependencyContainer {
  private static dependencies = new Map<string, any>()

  public static register<T>(token: string, instance: T) {
    DependencyContainer.dependencies.set(token, instance)
  }

  public static resolve<T>(token: string): T {
    const dependency = DependencyContainer.dependencies.get(token)
    if (!dependency) {
      throw new Error(`Dependency ${token} not found.`)
    }
    return dependency
  }

  public static update<T>(token: string, newInstance: T) {
    DependencyContainer.dependencies.set(token, newInstance)
  }
}

// 用于注册依赖的装饰器
function Injectable(token: string) {
  return function <T extends { new (...args: any[]): {} }>(constructor: T) {
    DependencyContainer.register(token, new constructor())
  }
}

// 负责监听值的变化并进行处理
function createReactiveObject<T extends object>(
  obj: T,
  onMutate: (key: PropertyKey, value: any) => void
): T {
  const handler = {
    get(target: T, key: PropertyKey, receiver: any) {
      const result = Reflect.get(target, key, receiver)
      return result
    },
    set(target: T, key: PropertyKey, value: any, receiver: any): boolean {
      const oldValue = target[key]
      const result = Reflect.set(target, key, value, receiver)
      if (oldValue !== value) {
        onMutate(key, value)
      }
      return result
    },
    deleteProperty(target: T, key: PropertyKey): boolean {
      if (key in target) {
        onMutate(key, undefined)
        return Reflect.deleteProperty(target, key)
      }
      return false
    }
  }

  return new Proxy(obj, handler)
}

function Inject(token: string) {
  return function (target: any, propertyKey: string | symbol) {
    const getter = () => {
      return DependencyContainer.resolve(token)
    }

    const setter = (newValue: any) => {
      DependencyContainer.update(token, newValue)
    }

    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true
    })
  }
}